﻿using AiBLSmartEdu.Module.SmartChemistry.API.DTOs;
using AiBLSmartEdu.Module.SmartPhysics.API.DTOs;
using AutoMapper;
using Domain;
using Domain.Entities;
using FrameworkCore.DI;
using FrameworkCore.Events;
using FrameworkCore.Extensions;
using FrameworkCore.Helpers;
using FrameworkCore.Interfaces;
using FrameworkCore.Models;
using FrameworkCore.Repositories;
using Microsoft.EntityFrameworkCore;

namespace AiBLSmartEdu.Module.Chemistry.API.Services;

#nullable disable

/// <summary>
/// 化学问题提问服务
/// </summary>
public class ChemistryAskServices : IScopedDependency
{
    private readonly IRepository<ChemistryAsk> _chemistryMessageRepository;
    private readonly IMapper _mapper;
    private readonly IEventPublisher _eventPublisher;
    private readonly ICurrentUserService _currentUserService;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="chemistryMessageRepository">仓储</param>
    /// <param name="mapper">对象映射</param>
    /// <param name="eventPublisher">事件发布</param>
    /// <param name="currentUserService">当前用户</param>
    public ChemistryAskServices(
        IRepository<ChemistryAsk> chemistryMessageRepository,
        IMapper mapper,
        IEventPublisher eventPublisher,
        ICurrentUserService currentUserService)
    {
        _chemistryMessageRepository = chemistryMessageRepository;
        _mapper = mapper;
        _eventPublisher = eventPublisher;
        _currentUserService = currentUserService;
    }

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="filter">分页输入模型</param>
    /// <returns></returns>
    public async Task<PageResult<ChemistryAskOutputModel>> PageAsync(ChemistryAskPaginationFilter filter)
    {
        return (await _chemistryMessageRepository.GetOrderedQueryable(query =>
        {
            return query.OrderByDescending(o=>o.Id)
            .WhereIf(!filter.Question.IsNullOrWhiteSpace(), x => x.Question.Contains(filter.Question))
            .WhereIf(filter.IsFavorited.HasValue, x => x.IsFavorited == filter.IsFavorited);

        }, filter).ProjectToPaginatedDataAsync<ChemistryAsk, ChemistryAskOutputModel>(
            filter.PageNumber,
            filter.PageSize,
            _mapper.ConfigurationProvider
        )).ToPageList();
    }

    /// <summary>
    /// 发起提问
    /// </summary>
    /// <param name="input">包含新问题信息的输入模型</param>
    /// <returns>一个表示异步操作的任务</returns>
    public async Task CreateAsync(ChemistryAskCreateInputModel input)
    {
        var model = _mapper.Map<ChemistryAsk>(input);
        await _chemistryMessageRepository.InsertAsync(model);
    }

    /// <summary>
    /// 修改答案
    /// </summary>
    /// <param name="input">输入模型</param>
    /// <returns></returns>
    public async Task UpdateAnswerAsync(ChemistryAskUpdateAnswerInputModel input)
    {
        var question = await _chemistryMessageRepository.GetByIdAsync(input.Id);
        ExceptionHelper.ThrowIfNull(question, "问题不存在");

        await _chemistryMessageRepository.UpdateAsync(x =>
            x.SetProperty(p => p.Answer, p => input.Answer)
             .SetProperty(p => p.Type, p => input.Type), w => w.Id == input.Id);
    }

    /// <summary>
    /// 修改答案
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="question">问题</param>
    /// <param name="answer">答案</param>
    /// <returns></returns>
    public async Task UpdateAnswerAsync(string userId, string question, string answer)
    {
        await _chemistryMessageRepository.UpdateAsync(x =>
            x.SetProperty(p => p.Answer, p => answer)
             .SetProperty(p => p.Type, MessageType.Text), w => w.CreatedBy == userId && w.Question == question);
    }

    /// <summary>
    /// 根据问题获取答案
    /// </summary>
    /// <param name="question">问题</param>
    /// <returns></returns>
    public async Task<string> GetAnswerByQuestionAsync(string question)
    {
        return (await _chemistryMessageRepository.Query(x => x.Question == question).FirstOrDefaultAsync())?.Answer ?? string.Empty;
    }

    /// <summary>
    /// 清空用户数据
    /// </summary>
    /// <returns></returns>
    public async Task ClearByUserIdAsync()
    {
        await _chemistryMessageRepository.DeleteAsync(x => x.CreatedBy == _currentUserService.UserId);
    }
}
